/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * JEvalFunctionWidget.java
 *
 * Created on May 12, 2010, 6:06:54 PM
 */

package com.cospandesign.gui.pubsub.widgets;

import pubsub.PubSubManager;
import dlcm.Member;
import dlcm.Structure;
import info.monitorenter.gui.chart.ITrace2D;
import info.monitorenter.gui.chart.traces.Trace2DLtd;
import java.util.Timer;
import java.util.TimerTask;
import net.sourceforge.jeval.EvaluationException;
import net.sourceforge.jeval.Evaluator;

/**
 *
 * @author cospan
 */
public class JEvalFunctionWidget extends javax.swing.JFrame implements Widget{

    Class DataClass;
    dlcm.Member mMember;
    private String expression;
    private String ChannelName;
    private String MemberName;
    private Structure mStructure;
    private PubSubManager Parent;
    ITrace2D LocalTrace;
    int UpdateRate = 100;
    double time = 0;
    TimerTask mTimerTask;
    Timer mTimer;
    //private JTextArea txtExpression;

    private Evaluator evaluator = new Evaluator();

    /** Creates new form JEvalFunctionWidget */
    public JEvalFunctionWidget() {
        initComponents();
        
    }

    public static String GetWidgetName() {
        return "JEval Widget";
    }

    public void ReceiveMessage(Structure structure) {
        //Do Nothing
    }

    public boolean CanUseMember(Member member) {
        return member != null && member.Data instanceof Double;
    }

    public void SetupWidget(String channelName, String memberName, Structure structure, PubSubManager parent) {
        ChannelName = channelName;
        MemberName = memberName;
        mStructure = structure;
        mMember = mStructure.getMember(memberName);
        Parent = parent;
        setTitle(memberName + " Text Box");
        setVisible(true);

        LocalTrace = new Trace2DLtd(200);
        LocalChart2D.addTrace(LocalTrace);
    }

    public void setWidgetVisibility(boolean visible) {
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */

        final class GenerateFunctionTask extends TimerTask {

      int t = 0;
      /**
      * Implements TimerTask's abstract run method.
      */
      public void run()
      {
          String result = "";
          try {
              evaluator.putVariable("x", String.valueOf(t++));
              result = evaluator.evaluate(expression);
          }
          catch(EvaluationException ee)
          {
            ee.printStackTrace();
          }
          if(result.equals(""))
            return;

          double res = Double.parseDouble(result);
          mStructure.getMember(MemberName).Data = res;
          LocalTrace.addPoint(time++, res);
          Parent.PublishStructure(ChannelName, mStructure);
      }

    }

    public void UpdateEvaluation (){
        expression = EvaluateTextField.getText();
        if (mTimerTask != null){
            mTimerTask.cancel();
        }
        if (mTimer != null){
            mTimer.cancel();
            mTimer.purge();
        }
        TimerTask mTimerTask = new GenerateFunctionTask();
        mTimer = new Timer();
        mTimer.scheduleAtFixedRate(mTimerTask, 0, UpdateRate);
        
    }
    public void UpdateTimeout (){
        String timerString;
        Integer timer;
        timerString = UpdateRateTextField.getText();
        try {
            timer = Integer.parseInt(timerString);
        }
        catch (NumberFormatException e ){

            timer = 100;
        }
        if (timer <= 0){
            timer = 100;
        }
        UpdateRate = timer;
        UpdateEvaluation();
    }
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        LocalChart2D = new info.monitorenter.gui.chart.Chart2D();
        EvaluateButton = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        EvaluateTextField = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        ExampleList = new javax.swing.JList();
        jLabel2 = new javax.swing.JLabel();
        UpdateRateTextField = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        UpdateTimeoutButton = new javax.swing.JButton();

        setIconImage(java.awt.Toolkit.getDefaultToolkit().getImage(getClass().getResource("/com/cospandesign/resources/cospandesign.png")));
        setName("JEvalFunctionWidget"); // NOI18N
        setResizable(false);

        LocalChart2D.setName("LocalChart2D"); // NOI18N

        javax.swing.GroupLayout LocalChart2DLayout = new javax.swing.GroupLayout(LocalChart2D);
        LocalChart2D.setLayout(LocalChart2DLayout);
        LocalChart2DLayout.setHorizontalGroup(
            LocalChart2DLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 396, Short.MAX_VALUE)
        );
        LocalChart2DLayout.setVerticalGroup(
            LocalChart2DLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 275, Short.MAX_VALUE)
        );

        EvaluateButton.setText("Evaluate");
        EvaluateButton.setName("EvaluateButton"); // NOI18N
        EvaluateButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EvaluateButtonActionPerformed(evt);
            }
        });

        jLabel1.setText("Eval Function");
        jLabel1.setName("jLabel1"); // NOI18N

        EvaluateTextField.setText("sin(#{x})");
        EvaluateTextField.setName("EvaluateTextField"); // NOI18N
        EvaluateTextField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                EvaluateTextFieldKeyPressed(evt);
            }
        });

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        ExampleList.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "sin(#{x})", "cos(#{x})", "tan(#{x})", "sin(#{x}/100)", "sqrt(#{x})" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        ExampleList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        ExampleList.setName("ExampleList"); // NOI18N
        ExampleList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                ExampleListValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(ExampleList);

        jLabel2.setText("Example");
        jLabel2.setName("jLabel2"); // NOI18N

        UpdateRateTextField.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
        UpdateRateTextField.setText("100");
        UpdateRateTextField.setName("UpdateRateTextField"); // NOI18N
        UpdateRateTextField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                UpdateRateTextFieldKeyPressed(evt);
            }
        });

        jLabel3.setText("Update Rate (mS)");
        jLabel3.setName("jLabel3"); // NOI18N

        UpdateTimeoutButton.setText("Update Timeout");
        UpdateTimeoutButton.setName("UpdateTimeoutButton"); // NOI18N
        UpdateTimeoutButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                UpdateTimeoutButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(jLabel1)
                        .addComponent(jLabel3)
                        .addComponent(EvaluateTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)
                        .addComponent(UpdateRateTextField)
                        .addComponent(EvaluateButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(UpdateTimeoutButton, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(LocalChart2D, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(LocalChart2D, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(EvaluateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(EvaluateButton)
                        .addGap(4, 4, 4)
                        .addComponent(jLabel3)
                        .addGap(7, 7, 7)
                        .addComponent(UpdateRateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(UpdateTimeoutButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE)
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 105, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void EvaluateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EvaluateButtonActionPerformed

        UpdateEvaluation();
    }//GEN-LAST:event_EvaluateButtonActionPerformed

    private void EvaluateTextFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_EvaluateTextFieldKeyPressed

        if (evt.getKeyChar() == evt.VK_ENTER) {
            UpdateEvaluation();
        }
    }//GEN-LAST:event_EvaluateTextFieldKeyPressed

    private void ExampleListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_ExampleListValueChanged
        String expr = (String) ExampleList.getSelectedValue();
        EvaluateTextField.setText(expr);
        UpdateEvaluation();
    }//GEN-LAST:event_ExampleListValueChanged

    private void UpdateRateTextFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_UpdateRateTextFieldKeyPressed
        if (evt.getKeyChar() == evt.VK_ENTER) {

        }
    }//GEN-LAST:event_UpdateRateTextFieldKeyPressed

    private void UpdateTimeoutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_UpdateTimeoutButtonActionPerformed
        UpdateTimeout();
    }//GEN-LAST:event_UpdateTimeoutButtonActionPerformed

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new JEvalFunctionWidget().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton EvaluateButton;
    private javax.swing.JTextField EvaluateTextField;
    private javax.swing.JList ExampleList;
    private info.monitorenter.gui.chart.Chart2D LocalChart2D;
    private javax.swing.JTextField UpdateRateTextField;
    private javax.swing.JButton UpdateTimeoutButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JScrollPane jScrollPane1;
    // End of variables declaration//GEN-END:variables

}
